/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bef.api.lcp;

import com.inspur.edp.bef.api.be.IBEService;
import com.inspur.edp.bef.api.parameter.retrieve.RespectiveRetrieveResult;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bef.api.parameter.save.SaveParameter;
import com.inspur.edp.cef.entity.condition.EntityFilter;
import com.inspur.edp.cef.spi.entity.resourceInfo.ModelResInfo;
import java.util.List;

/**
 * 标准的本地消费者代理，提供了外部程序调用的基本的操作接口，比如CRUD
 * <p>创建本类实例请使用{@link ILcpFactory}
 */
public interface IStandardLcp extends IBEService {

  /**
   * 上一次lcp调用过程中产生的内部变更和消息等信息
   */
  IResponseContext getResponseContext();

  /**
   * Bef的上下文信息接口
   */
  BefContext getBefContext();

  /**
   * 根据指定的过滤条件从持久化中查询满足条件的数据条数。
   * <p>
   * 如果一条数据在当前BefSession中有修改但未保存到持久化， 且此数据修改前不满足{@code filter}参数所代表的条件但修改后满足，那么这条数据将不会计入在结果中。
   *
   * @param filter 过滤条件
   * @return 符合过滤条件的数据的行数
   */
  int getResultCount(EntityFilter filter);

  /**
   * 使用默认保存参数{@link SaveParameter#getDefault()}进行保存。
   * <p>此方法与{@link #save(SaveParameter)}方法类似，请务必仔细阅读{@link #save(SaveParameter)}方法上说明文档。
   *
   * @see #save(SaveParameter)
   */
  void save();

  /**
   * 使用指定的保存参数{@link SaveParameter}将当前BefSession下的全部变更集（包括当前业务实体所有数据以及可能存在的其他类型的业务实体所有数据）提交到持久化。
   * <p>提交到持久化前，自动使用{@link javax.transaction.Transactional}注解（所有参数使用默认值）的方式开启一个数据库事务，
   * 当前业务实体的多行数据所产生的变更和可能存在的其他所有业务实体的变更，以及保存前联动计算、保存前校验规则的逻辑将全部包含在上述数据库事务中。
   * 例如，在一个BefSession下创建了一条销售订单业务实体数据和一条发票业务实体数据，那么调用销售订单的save方法将会同时保存销售订单和发票，且两者必定在一个数据库事务中。
   * <p>请注意，此方法仅支持在视图模型动作等外部进行调用，禁止在联动计算、校验规则、业务实体自定义动作、业务实体实体动作中
   * 对当前Session下的{@code IStandardLcp}调用{@code save()}，除非创建新的Session，然后创建新的{@code IStandardLcp}后，可以调用新{@code IStandardLcp}的{@code save()}。
   * 创建新的Session请使用{@link com.inspur.edp.bef.api.services.IBefSessionManager}。
   *
   * @param par 保存使用的参数，如遇特殊场景需要指定保存参数，可以new一个{@link SaveParameter}并对其上选项进行赋值后传入本方法
   *
   * @see SaveParameter
   * @see SaveParameter#getDefault()
   */
  void save(SaveParameter par);

  /**
   * 1.取消当前业务实体上已提交到缓存、但未保存到持久化中的变更集；
   * <p>
   * 2.释放当前业务实体下所有的数据锁；
   */
  void cancel();

  /**
   * 1.取消当前业务实体已提交到缓存、但未保存到持久化中的变更集；
   * <p>
   * 2.释放当前业务实体下所有的数据锁；
   * <p>
   * 3.清空当前业务实体上缓存中的所有数据缓存。
   */
  void cleanUp();

  /**
   * 根据节点编号获取节点的ID标识
   *
   * @param nodeCode 节点的编号
   * @return 节点ID
   */
  String getNodeId(String nodeCode);

  /**
   * 获取主节点的ID标识
   *
   * @return 主节点ID
   */
  String getMainNodeId();

  /**
   * 根据节点ID检索指定数据ID的业务实体数据。
   *
   * @param nodeId        节点ID
   * @param dataId        数据ID
   * @param retrieveParam 检索数据时的参数
   * @return 检索返回的结果
   */
  RespectiveRetrieveResult retrieve(
      String nodeId, String dataId, RetrieveParam retrieveParam);

  /**
   * 根据数据ID判断数据是否存在（包括目前在内存中还没保存的数据以及已删除的数据）
   *
   * @param dataId 数据主键
   * @return 数据是否存在
   */
  boolean exists(String dataId);

  void generateTable(String nodeCode);

  void dropTable(String nodeCode);

  java.util.Collection<String> getDataIds();

  void setRepositoryVariables(String key, String value);

  /**
   * 执行action保证其中的所有be操作的事务性(同时成功同时失败)
   */
  void atomicallyInvoke(Runnable action);

  /**
   * 获取模型相关信息
   *
   * @return 模型信息类
   */
  ModelResInfo getModelInfo();

  Object createPropertyDefaultValue(String nodeCode, String propertyName);

  List<String> getDistinctFJM(String fjnPropertyName, EntityFilter filter, Integer parentLayer);
}
